package com.wz.jiangsu.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@EnableAsync
@Configuration
public class ExecutorConfig {

	// 获取服务器的 cpu 个数
	private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();

    @Bean("taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心线程数
        executor.setCorePoolSize(CPU_COUNT * 2);
        // 最大线程数 (核心线程数 + 空闲线程数)
        executor.setMaxPoolSize(CPU_COUNT * 4);
        // 空闲线程生存时间 (生存时间内没有新任务，此线程资源会释放)
        executor.setKeepAliveSeconds(50);
        // 阻塞队列大小，当没有主线程空闲时，新任务会加入阻塞队列排队，队列满了会创建非核心线程（空闲线程）处理任务
        executor.setQueueCapacity(5000);
        // 线程名前缀
        executor.setThreadNamePrefix("测试");
		// 设置拒绝策略
		// AbortPolicy 	          ->    默认策略，如果阻塞队列满了丢掉这个任务并且抛出 RejectedExecutionException 异常
		// DiscardPolicy          ->    如果阻塞队列满了，会直接丢掉这个任务并且不会有任何异常
		// DiscardOldestPolicy    ->	如果阻塞队列满了，会将最早进入队列的任务删掉腾出空间，再尝试加入队列
		// CallerRunsPolicy       ->	如果添加到线程池失败，那么主线程会自己去执行该任务，不会等待线程池中的线程去执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 等待所有任务结束后再关闭线程池
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.initialize();
        return executor;
    }
}
